package com.desire.test;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

import static com.desire.test._41_countDownLatch.latch;

/**
 * 一个线程往集合里添加元素  ,  另一个线程 监控 当元素个数达到5个时  打印一句话
 *
 * @author desire
 */

public class _41_countDownLatch {

    static volatile volatile1 ms = new volatile1();

    static CountDownLatch latch = new CountDownLatch(1);

    /**
     * 方法二  CountDownLatch
     *
     * @param args
     */
    public static void main(String[] args) {
        //CountDownLatch
        //T1 任务向容器中添加元素，到5个元素时，打开门栓通知线程T2
        new Thread(cdl::add, "T1").start();
        //T2 启动就进入就绪等待，接到通知就开始向下执行。
        new Thread(cdl::count, "T2").start();
    }


    /**
     * 方法一   一个线程往集合里添加元素  ,  另一个线程 监控 当元素个数达到5个时  打印一句话
     *
     * @param args
     */
    public static void main1(String[] args) {
        new Thread(() -> {
            System.out.println("监控元素线程启动 " + Thread.currentThread().getName());
            while (!ms.count()) {
            }
            System.out.print("已经有五个了   ");
            System.out.println(Thread.currentThread().getName() + " 线程达到标准");
        }, "监控线程count").start();

        new Thread(() -> {
            System.out.println("添加元素线程启动 " + Thread.currentThread().getName());
            for (int i = 1; i <= 20; i++) {
                ms.add();
                try {
                    TimeUnit.SECONDS.sleep(1);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }, "添加线程add").start();


    }
}


class cdl {
    static List<String> list1 = new ArrayList<String>();

    public static void add() {
        String name = Thread.currentThread().getName();
        System.out.println(name + " 线程启动");
        while (true) {
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            list1.add("item" + (list1.size() + 1));
            System.out.println(String.format("%s:%d = %s", name, list1.size(), list1.get(list1.size() - 1)));
            if (list1.size() == 5) {
                // 开启门栓, 此时会提醒线程二向下执行
                latch.countDown();
            }
        }
    }

    /**
     * 此线程一启动就运行, 当另一个线程调用 latch.countDown(); 方法时, 此线程 latch.await(); 方法放开执行此语句下方的代码
     */
    public static void count() {
        String tn = Thread.currentThread().getName();
        System.out.println(tn + ":线程启动");
        try {
            latch.await();//此线程中断在此处，等待
            System.out.println(tn + ":容器中已经有五个元素了,线程结束 。");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

class volatile1 {
    private final List<String> list = new ArrayList<>();

    /**
     * 添加元素线程
     */
    public void add() {
        list.add("add" + list.size());
        System.out.printf("%d = %s%n", list.size(), list.get(list.size() - 1));
    }

    /**
     * 监控线程 ,到 5个就打印出引出一句话
     *
     * @return 有没有到  5 个元素
     */
    public boolean count() {
        return list.size() == 5;
    }
}

